package com.scsj.cloud.base.util;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;

import javax.crypto.Cipher;

import org.springframework.stereotype.Component;

import sun.security.rsa.RSAPrivateCrtKeyImpl;
import sun.security.rsa.RSAPublicKeyImpl;

@SuppressWarnings("restriction")
@Component
public class RSAUtil {

    private static final String ALGORITHM = "RSA";
    
    private static final String RAS_PATH = "/usr/rsa";

    /**
     * 生成密钥对
     * 
     * @param keyLength
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static KeyPair genKeyPair(int keyLength) throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
        keyPairGenerator.initialize(keyLength);
        return keyPairGenerator.generateKeyPair();
    }


    /**
     * 以base64编码保存密钥
     * 
     * @param key
     * @param path
     * @throws IOException
     */
    public static void saveKey(Key key, String path) throws IOException {
        Path keyPath = Paths.get(path);
        Files.write(keyPath, Base64.getEncoder().encode(key.getEncoded()));
    }

    /**
     * 读取公钥
     * 
     * @param path
     * @return
     * @throws Exception
     */
	public static PublicKey readPublicKey(String path) throws Exception {
    	
        Path keyPath = Paths.get(path);
        byte[] keyBytes = Files.readAllBytes(keyPath);
        return new RSAPublicKeyImpl(Base64.getDecoder().decode(keyBytes));
    }

    /**
     * 读取密钥
     * 
     * @param path
     * @return
     * @throws Exception
     */
	public static PrivateKey readPrivateKey(String path) throws Exception {
        Path keyPath = Paths.get(path);
        byte[] keyBytes = Files.readAllBytes(keyPath);
        return RSAPrivateCrtKeyImpl.newKey(Base64.getDecoder().decode(keyBytes));
    }


    /**
     * 公钥加密
     * 
     * @param content
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static String encrypt(String content, PublicKey publicKey) throws Exception {
        // 选择算法,创建实例
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        // 选择模式,结合公钥初始化
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        // 加密
        byte[] result = cipher.doFinal(content.getBytes());
        // 转码
        String base64Result = Base64.getEncoder().encodeToString(result);
        return base64Result;
    }

    /**
     * 私钥解密
     * @param content
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static String decrypt(String content, PrivateKey privateKey) throws Exception {
        // 创建实例
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        // 初始化
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        // 转码
        byte[] encodedBytes = Base64.getDecoder().decode(content.getBytes());
        // 解密
        byte[] result = cipher.doFinal(encodedBytes);
        return new String(result);
    }
    
    /**
     * 加密(自己)
     * 
     * @param data
     * @return
     * @throws Exception
     */
    public String RSAEncryption(String data) throws Exception{
        // 获取公钥
        PublicKey pubKey = RSAUtil.readPublicKey(RAS_PATH+"/rsa.pub");
        // 公钥加密
        String encrypt = RSAUtil.encrypt(data, pubKey);
        // 返回加密信息
        return encrypt;
    }
    
    /**
     * 解密(自己)
     * 
     * @param data
     * @return
     * @throws Exception
     */
    public String RSADecryption(String data) throws Exception{
    	// 获取私钥
        PrivateKey priKey = RSAUtil.readPrivateKey(RAS_PATH+"/rsa.pri");
        // 私钥解密
        String decrypt = decrypt(data, priKey);
    	// 返回解密信息
    	return decrypt;
    }


}
